
(function ($) {
	'use strict';

	var path = require('path');
	var fs = require('fs');
	var http = require('http');

	const CURRENT_USER = 'CURRENT_USER';
	const CUSTOM_EMOTICON = 'CUSTOM_EMOTICON';

	function getImageIndex(images, image) {
		for (var i = 0, len = images.length; i < len; i++) {
			if (image.mediaId === images[i].mediaId
				&& image.deliveryId === images[i].deliveryId) {
				return i;
			}
		}

		return -1;
	}

	$(document).ready(function () {
		var win = require('nw.gui').Window.get();
		var options = {
			pageScale: 0,     /* pageScale: 0: origin/1: max/-1: min */
			imgScale: 0,
			rotate: 0,
			imgMaxWidth: 10000,
			imgMinWidth: 50
		};
		// win.showDevTools();
		var $imgContainer = $('.img-container');
		var $imgPreview = $('.img-preview');
		var $imgLoading = $('.img-loading');
		var $btnClose = $('.btn-close');
		var $btnMinimize = $('.btn-minimize');
		var $btnMaxmize = $('.btn-maximize');
		var $prevWrapper = $('.prev-wrapper');
		var $nextWrapper = $('.next-wrapper');
		var $iconPrev = $('.icon-prev');
		var $iconNext = $('.icon-next');
		var $footer = $('.footer');
		var $iconZoomIn = $('.icon-zoom-in');
		var $iconZoomOut = $('.icon-zoom-out');
		var $iconRotate = $('.icon-rotate');
		var $iconDownload = $('.icon-download');
		var $iconCollect = $('.icon-collect');
		var $tipBox = $('.tip-box');

		var parentWindow = window.opener;

		_init();
		function _init() {
			/* auto focus when opened */
			win.focus();

			/* different system class name */
			if (window.navigator.userAgent.indexOf('Mac') > -1) {
				$('body').addClass('mac-os');
			} else {
				$('body').addClass('windows-os');
			}

			/* get current image src and show it */
			currentImageChangeFn(true);

			/* show watermark or not */
			watermarkInit({});

			/* readonly */
			var imagePreview = parentWindow.imagePreview;
			if (imagePreview.options.readOnly) {
				$iconDownload.addClass('hidden');
				$iconCollect.addClass('hidden');
			} else {
				$iconDownload.removeClass('hidden');
				$iconCollect.removeClass('hidden');
			}

			/* http or https */
			if (imagePreview.options.isHttps) {
				http = require('https');
			}

		}

		function isImageInCollection(imageItem) {
			let currentUser = JSON.parse(localStorage.getItem(CURRENT_USER)) || {};
			let customEmoticon = JSON.parse(localStorage.getItem(CUSTOM_EMOTICON)) || {};

			if (!currentUser || !customEmoticon) {
				return false;
			}

			let currentUserId = currentUser['user_id'];
			let currentUserCustomEmoticon = customEmoticon[currentUserId] || [];

			return currentUserCustomEmoticon.indexOf(imageItem.mediaId) > -1;
		}

		function toastr(msg, toastrType) {
			if (typeof msg === 'undefined') {
				return;
			}

			var $toastr = $('.toastr', $imgContainer);
			$toastr.remove();
			$toastr = $('<div class="toastr"></div>');

			if (toastrType === 'success' || toastrType === 'error' || toastrType === 'warning') {
				$toastr.addClass(toastrType);
			}
			$toastr.text(msg);

			$imgContainer.append($toastr);
			$toastr.fadeIn(300);

			setTimeout(function () {
				$toastr.fadeOut(500);
			}, 2 * 1000);
		}

		function currentImageChangeFn(flag) {
			var imagePreview = parentWindow.imagePreview;
			var timeoutHandler = null;

			options.rotate = 0;

			/* remove and append to reset image state */
			$imgPreview.remove();
			$imgPreview = $('<img class="img-preview">');
			$imgContainer.prepend($imgPreview);
			$imgPreview.css('transform', 'translate(-50%, -50%) rotate(' + options.rotate + 'deg)')
				.attr('src', imagePreview.currentImage.mediaUrl)
				.addClass('visible-hidden');

			/* loading status */
			$footer.addClass('visible-hidden');
			$imgLoading.removeClass('visible-hidden');
			$imgPreview.load(function (evt) {
				$imgLoading.addClass('visible-hidden');
				$imgPreview.removeClass('visible-hidden');
				$footer.removeClass('visible-hidden');
			});

			/* rebind elem events starts */
			elem = $imgPreview[0];
			elem.addEventListener('mousedown', function (evt) {
				evt.preventDefault();

				startX = evt.pageX;
				startY = evt.pageY;

				if (!startPosition) {
					startPosition = {
						x: elem.clientLeft - parent.clientLeft + parent.clientWidth / 2,
						y: elem.clientTop - parent.clientTop + parent.clientHeight / 2
					};
				}
				elem.addEventListener('mousemove', onMove);
			});

			elem.addEventListener('mouseup', function (evt) {
				evt.stopPropagation();

				startPosition = {
					x: startPosition.x + (evt.pageX - startX),
					y: startPosition.y + (evt.pageY - startY)
				};
				elem.removeEventListener('mousemove', onMove);
			});
			/* rebind elem events ends */

			var index = getImageIndex(imagePreview.images, imagePreview.currentImage);

			/* check if current image is in collection */
			if (isImageInCollection(imagePreview.currentImage)) {
				imagePreview.currentImage.inCollection = true;
				$iconCollect.addClass('in-collection');
			} else {
				imagePreview.currentImage.inCollection = false;
				$iconCollect.removeClass('in-collection');
			}

			/* flag === true when this first initiated */
			if (flag) {
				$tipBox.text((index + 1) + '/' + imagePreview.images.length);
				$tipBox.fadeIn(500);
				return;
			}

			if (index === 0) {
				$tipBox.text('已是第一张');
				$tipBox.fadeIn(500);

				setTimeout(function () {
					$tipBox.fadeOut(500);
				}, 1 * 1000);
			} else if (index === imagePreview.images.length - 1) {
				$tipBox.text('已是最后一张');
				$tipBox.fadeIn(500);

				setTimeout(function () {
					$tipBox.fadeOut(500);
				}, 1 * 1000);
			} else {
				$tipBox.text((index + 1) + '/' + imagePreview.images.length);
				$tipBox.fadeIn(500);
			}
		}

		function watermarkInit(config) {
			let $watermarkLayer = $('.watermark-layer', $imgContainer);
			if ($watermarkLayer.length > 0) {
				$watermarkLayer = $($watermarkLayer.get(0));
			} else {
				$watermarkLayer = $('<div class="watermark-layer"></div>');
				$imgContainer.append($watermarkLayer);
			}

			/* get watermark url */
			let url = parentWindow.imagePreview.options.watermarkConfig.watermarkBgUrl;
			$watermarkLayer.css('backgroundImage', "url('" + url + "')");
		}

		/* this expect to work only when develop
		var count = 0;
		$tipBox.on('click', function () {
			if (count === 3) {
				count = 0;
				win.showDevTools();
			} else {
				count++;
			}
		});
		 */

		/* window operations events starts */
		$btnClose.on('click', function () {
			win.close(true);
		});

		$btnMinimize.on('click', function () {
			options.pageScale = -1;
			win.minimize();
		});

		$btnMaxmize.on('click', function () {
			if (options.pageScale !== 1) {
				win.maximize();
				options.pageScale = 1;
			} else {
				win.unmaximize();
				options.pageScale = 0;
			}
		});

		win.on('resize', function (width, height) {
			var imgWidth = $imgPreview.width();
			var imgHeight = $imgPreview.height();

			$imgPreview.offset({
				'left': (width - imgWidth) / 2,
				'top': (height - imgHeight) / 2
			});
			startPosition = {
				x: elem.clientLeft - parent.clientLeft + parent.clientWidth / 2,
				y: elem.clientTop - parent.clientTop + parent.clientHeight / 2
			};
		});
		/* window operations events ends */

		$iconPrev.on('click', function () {
			var imagePreview = parentWindow.imagePreview;
			var index = getImageIndex(imagePreview.images, imagePreview.currentImage);

			if (index > 0) {
				imagePreview.currentImage = imagePreview.images[index - 1];

				currentImageChangeFn();
			}

			if (index - 1 === 0) {
				$(this).addClass('visible-hidden');
			}
		});

		$iconNext.on('click', function () {
			var imagePreview = parentWindow.imagePreview;
			var index = getImageIndex(imagePreview.images, imagePreview.currentImage);

			if (index < imagePreview.images.length - 1) {
				imagePreview.currentImage = imagePreview.images[index + 1];

				currentImageChangeFn();
			}
			if (index + 1 === imagePreview.images.length - 1) {
				$(this).addClass('visible-hidden');
			}
		});

		/**
		 * img - zoomin
		 */
		$iconZoomIn.on('click', function () {
			var width = $imgPreview.css('width');
			width = parseInt(width.substring(0, width.length - 2), 10);
			if (width > 10000) {
				return;
			}

			$imgPreview.addClass('scroll');
			width += 20;
			$imgPreview.css('width', width + 'px');
		});

		/**
		 * img -zoomout
		 */
		$iconZoomOut.on('click', function () {
			var width = $imgPreview.css('width');
			width = parseInt(width.substring(0, width.length - 2), 10);

			if (width < 50) {
				return;
			}

			$imgPreview.addClass('scroll');
			width -= 20;
			$imgPreview.css('width', width + 'px');
		});

		/**
		 * img - rotate
		 */
		$iconRotate.on('click', function () {
			options.rotate = options.rotate + 90;

			if (options.rotate % 360 === 0) {
				options.rotate = 0;
			}

			$imgPreview.css('transform', 'translate(-50%, -50%) rotate(' + options.rotate + 'deg)');
		});

		function getFileType(image) {
			return image.isGif ? '.gif' : '.png';
		}

		function getFileName(image) {
			return image.isGif ? (image.deliveryId + '.gif') : (image.deliveryId + '.png');
		}

		function getDefaultDownloadPath() {
			return path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 'Documents\\');
		}

		function getDownloadPath() {
			var currentUser = JSON.parse(localStorage.getItem('CURRENT_USER'));
			var lastTimeDownloadPath = JSON.parse(localStorage.getItem('LAST_TIME_DOWNLOAD_PATH')) || {};

			if (!currentUser) { return ''; }
			lastTimeDownloadPath = lastTimeDownloadPath[currentUser.user_id] || getDefaultDownloadPath();

			return lastTimeDownloadPath;
		}

		function downloadFile(mediaUrl, filePath) {
			return new Promise(function (resolve, reject) {
				var file = fs.createWriteStream(filePath);

				var req = http.get(mediaUrl, function (res) {
					if (res.statusCode !== 200) {
						reject(res);
					} else {
						res.pipe(file);
					}

					res.on('data', function (chunk) {
						// console.log('chunk:', chunk);
					}).on('end', function (data) {
						console.log('end:', data);
						resolve(data);
					}).on('error', function (err) {
						console.log('download image error:', err);
					});
				});
			});
		}

		/**
		 * img - download
		 */
		$iconDownload.on('click', function () {
			var currentImage = parentWindow.imagePreview.currentImage;
			var mediaUrl = currentImage.mediaUrl;

			var $downloadFile = $('#downloadFile');
			$downloadFile.remove();

			$downloadFile = $(`<input type="file" id="downloadFile" style="display: none;" >`);
			$('body').append($downloadFile);

			$downloadFile.attr('accept', getFileType(currentImage))
				.attr('nwsaveas', path.resolve(getDownloadPath(), getFileName(currentImage)))
				.on('change', function (evt) {
					var mediaUrl = currentImage.mediaUrl;
					var filePath = this.value;

					downloadFile(mediaUrl, filePath)
						.then(function (data) {
							toastr('图片下载成功!', 'success');
						}, function (data) {
							toastr('图片下载失败!', 'error');
						}, function (data) {
							console.log('progress:', data);
						});
				});

			$downloadFile.trigger('click');
		});

		/* todo: collect */
		$iconCollect.on('click', function () {
			let imagePreview = parentWindow.imagePreview;

			toggleCollect();
		});

		/* add in/remove from collection */
		function toggleCollect() {
			let imagePreview = parentWindow.imagePreview;
			let currentUser = JSON.parse(localStorage.getItem(CURRENT_USER));
			let customEmoticon = JSON.parse(localStorage.getItem(CUSTOM_EMOTICON)) || {};

			if (!currentUser) {
				console.log('Get current user info error');
				return false;
			}

			let currentUserId = currentUser['user_id'];
			let currentUserCustomEmoticon = customEmoticon[currentUserId] || [];

			if (imagePreview.currentImage.inCollection) {
				currentUserCustomEmoticon.splice(currentUserCustomEmoticon.indexOf(imagePreview.currentImage.mediaId), 1);

				imagePreview.currentImage.inCollection = false;
				$iconCollect.removeClass('in-collection');
			} else {
				currentUserCustomEmoticon.push(imagePreview.currentImage.mediaId);

				imagePreview.currentImage.inCollection = true;
				$iconCollect.addClass('in-collection');
			}
			customEmoticon[currentUserId] = currentUserCustomEmoticon;
			localStorage.setItem(CUSTOM_EMOTICON, JSON.stringify(customEmoticon));
		}

		/**
		 * img-container wheel
		 */
		$imgContainer.on('wheel', function (evt) {
			var delta = evt.originalEvent.wheelDelta,
				wheelScale = delta / 120;

			var width = $imgPreview.css('width');
			width = parseInt(width.substring(0, width.length - 2), 10);

			if ((width > options.imgMaxWidth && wheelScale > 0)
				|| (width < options.imgMinWidth && wheelScale < 0)) {
				return;
			}
			$imgPreview.addClass('scroll');

			if (wheelScale > 0) {
				width += 20;
			} else {
				width -= 20;
			}
			$imgPreview.css('width', width + 'px');
		});

		/**
		 * img- move
		 */
		var startX, startY, startPosition;
		var elem = $imgPreview[0];
		var parent = elem.offsetParent;

		function onMove(evt) {
			evt.stopPropagation();

			elem.style.top = startPosition.y + (evt.pageY - startY) + 'px';
			elem.style.left = startPosition.x + (evt.pageX - startX) + 'px';
		}

		elem.addEventListener('mousedown', function (evt) {
			evt.preventDefault();

			startX = evt.pageX;
			startY = evt.pageY;

			if (!startPosition) {
				startPosition = {
					x: elem.clientLeft - parent.clientLeft + parent.clientWidth / 2,
					y: elem.clientTop - parent.clientTop + parent.clientHeight / 2
				};
			}
			elem.addEventListener('mousemove', onMove);
		});


		elem.addEventListener('mouseup', function (evt) {
			evt.stopPropagation();

			startPosition = {
				x: startPosition.x + (evt.pageX - startX),
				y: startPosition.y + (evt.pageY - startY)
			};
			elem.removeEventListener('mousemove', onMove);
		});

		$prevWrapper.hover(function (evt) {
			var imagePreview = parentWindow.imagePreview;
			var index = getImageIndex(imagePreview.images, imagePreview.currentImage);

			if (index > 0) {
				$iconPrev.removeClass('visible-hidden');
			}
		}, function (evt) {
			$iconPrev.addClass('visible-hidden');
		});

		$nextWrapper.hover(function (evt) {
			var imagePreview = parentWindow.imagePreview;
			var index = getImageIndex(imagePreview.images, imagePreview.currentImage);

			if (index < imagePreview.images.length - 1) {
				$iconNext.removeClass('visible-hidden');
			}
		}, function (evt) {
			$iconNext.addClass('visible-hidden');
		});
	});

})(jQuery);